Q-2 Alternative: Canvas & Paints OR Fade In & Zoom Out Animation (5 Marks)
Questions​
a) Write a note on working of canvas and paints in android application. (5 marks)
OR
b) Write a code to demonstrate the use of 'Fade In' and 'Zoom Out' animation in android application. (5 marks)
Answers​
a) Canvas and Paints in Android Application​
Canvas Overview​
Canvas is a 2D drawing surface in Android that provides methods for drawing graphics, text, and images. It acts as a drawing board where you can draw shapes, paths, text, and bitmaps.
Paint Overview​
Paint is a class that holds styling and color information about how to draw geometries, text, and bitmaps on the Canvas.
Key Concepts​
1. Canvas Functionality
- Drawing Surface: Provides 2D drawing capabilities
- Coordinate System: Uses (0,0) at top-left corner
- Drawing Methods: Lines, rectangles, circles, paths, text, bitmaps
- Transformations: Rotate, scale, translate, skew
- Clipping: Restrict drawing to specific regions
2. Paint Properties
- Color: Set drawing color
- Style: Fill, stroke, or both
- Stroke Width: Line thickness
- Anti-aliasing: Smooth edges
- Text Properties: Size, typeface, alignment
Canvas Drawing Methods​
// Basic shapes
canvas.drawRect(left, top, right, bottom, paint);
canvas.drawCircle(cx, cy, radius, paint);
canvas.drawLine(startX, startY, stopX, stopY, paint);
canvas.drawOval(oval, paint);
// Text
canvas.drawText(text, x, y, paint);
// Bitmaps
canvas.drawBitmap(bitmap, x, y, paint);
// Paths
Path path = new Path();
path.moveTo(x1, y1);
path.lineTo(x2, y2);
canvas.drawPath(path, paint);
Complete Example: Custom Drawing View​
public class CustomDrawingView extends View {
private Paint paintCircle, paintRect, paintText, paintLine;
private Path customPath;
public CustomDrawingView(Context context) {
super(context);
initPaints();
}
public CustomDrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaints();
}
private void initPaints() {
// Paint for filled circle
paintCircle = new Paint();
paintCircle.setColor(Color.BLUE);
paintCircle.setStyle(Paint.Style.FILL);
paintCircle.setAntiAlias(true);
// Paint for rectangle outline
paintRect = new Paint();
paintRect.setColor(Color.RED);
paintRect.setStyle(Paint.Style.STROKE);
paintRect.setStrokeWidth(5f);
paintRect.setAntiAlias(true);
// Paint for text
paintText = new Paint();
paintText.setColor(Color.BLACK);
paintText.setTextSize(48f);
paintText.setTypeface(Typeface.DEFAULT_BOLD);
paintText.setAntiAlias(true);
// Paint for lines
paintLine = new Paint();
paintLine.setColor(Color.GREEN);
paintLine.setStrokeWidth(3f);
paintLine.setAntiAlias(true);
// Create custom path
customPath = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Get canvas dimensions
int width = getWidth();
int height = getHeight();
// Draw background
canvas.drawColor(Color.LTGRAY);
// Draw filled circle
canvas.drawCircle(width * 0.2f, height * 0.2f, 50f, paintCircle);
// Draw rectangle outline
canvas.drawRect(width * 0.1f, height * 0.4f,
width * 0.4f, height * 0.6f, paintRect);
// Draw text
canvas.drawText("Custom View", width * 0.1f, height * 0.8f, paintText);
// Draw lines
canvas.drawLine(0, height * 0.5f, width, height * 0.5f, paintLine);
canvas.drawLine(width * 0.5f, 0, width * 0.5f, height, paintLine);
// Draw custom path (triangle)
customPath.reset();
customPath.moveTo(width * 0.7f, height * 0.2f);
customPath.lineTo(width * 0.9f, height * 0.4f);
customPath.lineTo(width * 0.5f, height * 0.4f);
customPath.close();
Paint pathPaint = new Paint();
pathPaint.setColor(Color.MAGENTA);
pathPaint.setStyle(Paint.Style.FILL);
canvas.drawPath(customPath, pathPaint);
// Draw arc
RectF arcRect = new RectF(width * 0.6f, height * 0.6f,
width * 0.9f, height * 0.9f);
canvas.drawArc(arcRect, 0, 180, true, paintCircle);
}
// Method to change colors dynamically
public void setCircleColor(int color) {
paintCircle.setColor(color);
invalidate(); // Trigger redraw
}
}
Using Custom View in Activity​
public class MainActivity extends AppCompatActivity {
private CustomDrawingView customView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create and set custom view
customView = new CustomDrawingView(this);
setContentView(customView);
// Optional: Add to existing layout
// LinearLayout layout = findViewById(R.id.container);
// layout.addView(customView);
}
}
Advanced Paint Techniques​
// Gradient effects
LinearGradient gradient = new LinearGradient(0, 0, 100, 100,
Color.RED, Color.BLUE, Shader.TileMode.MIRROR);
paint.setShader(gradient);
// Shadow effects
paint.setShadowLayer(10f, 5f, 5f, Color.GRAY);
// Dash effects
DashPathEffect dashEffect = new DashPathEffect(new float[]{10, 5}, 0);
paint.setPathEffect(dashEffect);
// Blur effects
BlurMaskFilter blur = new BlurMaskFilter(15, BlurMaskFilter.Blur.NORMAL);
paint.setMaskFilter(blur);
b) Fade In and Zoom Out Animation Implementation​
Step 1: Create Animation XML Files​
res/anim/fade_in_animation.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="1500"
android:fillAfter="true" />
</set>
res/anim/zoom_out_animation.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="0.1"
android:toYScale="0.1"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"
android:fillAfter="true" />
</set>
res/anim/combined_fade_zoom.xml (Optional combined animation):
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="1500" />
<scale
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="0.0"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1500" />
</set>
Step 2: Layout XML​
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<ImageView
android:id="@+id/fadeInImage"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:src="@drawable/ic_star"
android:alpha="0.0" />
<TextView
android:id="@+id/zoomOutText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/fadeInImage"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:text="Zoom Out Text"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="@android:color/holo_blue_dark" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/zoomOutText"
android:layout_centerHorizontal="true"
android:layout_marginTop="80dp"
android:orientation="vertical">
<Button
android:id="@+id/btnFadeIn"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Start Fade In"
android:layout_marginBottom="16dp" />
<Button
android:id="@+id/btnZoomOut"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Start Zoom Out"
android:layout_marginBottom="16dp" />
<Button
android:id="@+id/btnReset"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Reset Views"
android:layout_marginBottom="16dp" />
<Button
android:id="@+id/btnCombined"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Combined Animation" />
</LinearLayout>
</RelativeLayout>
Step 3: MainActivity Java Code​
public class MainActivity extends AppCompatActivity {
private ImageView fadeInImage;
private TextView zoomOutText;
private Button btnFadeIn, btnZoomOut, btnReset, btnCombined;
private Animation fadeInAnimation, zoomOutAnimation, combinedAnimation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
loadAnimations();
setupClickListeners();
}
private void initViews() {
fadeInImage = findViewById(R.id.fadeInImage);
zoomOutText = findViewById(R.id.zoomOutText);
btnFadeIn = findViewById(R.id.btnFadeIn);
btnZoomOut = findViewById(R.id.btnZoomOut);
btnReset = findViewById(R.id.btnReset);
btnCombined = findViewById(R.id.btnCombined);
}
private void loadAnimations() {
fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_in_animation);
zoomOutAnimation = AnimationUtils.loadAnimation(this, R.anim.zoom_out_animation);
combinedAnimation = AnimationUtils.loadAnimation(this, R.anim.combined_fade_zoom);
// Set animation listeners
fadeInAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(MainActivity.this, "Fade In Started", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(MainActivity.this, "Fade In Completed", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
zoomOutAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(MainActivity.this, "Zoom Out Started", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(MainActivity.this, "Zoom Out Completed", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
}
private void setupClickListeners() {
btnFadeIn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startFadeInAnimation();
}
});
btnZoomOut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startZoomOutAnimation();
}
});
btnReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
resetViews();
}
});
btnCombined.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCombinedAnimation();
}
});
}
private void startFadeInAnimation() {
fadeInImage.setAlpha(0.0f); // Start invisible
fadeInImage.startAnimation(fadeInAnimation);
}
private void startZoomOutAnimation() {
zoomOutText.setScaleX(1.0f); // Reset scale
zoomOutText.setScaleY(1.0f);
zoomOutText.startAnimation(zoomOutAnimation);
}
private void resetViews() {
// Clear animations
fadeInImage.clearAnimation();
zoomOutText.clearAnimation();
// Reset properties
fadeInImage.setAlpha(0.0f);
zoomOutText.setScaleX(1.0f);
zoomOutText.setScaleY(1.0f);
Toast.makeText(this, "Views Reset", Toast.LENGTH_SHORT).show();
}
private void startCombinedAnimation() {
zoomOutText.startAnimation(combinedAnimation);
}
}
Alternative: Programmatic Animation Creation​
// Create fade in animation programmatically
private Animation createFadeInAnimation() {
AlphaAnimation fadeIn = new AlphaAnimation(0.0f, 1.0f);
fadeIn.setDuration(1500);
fadeIn.setFillAfter(true);
return fadeIn;
}
// Create zoom out animation programmatically
private Animation createZoomOutAnimation() {
ScaleAnimation zoomOut = new ScaleAnimation(
1.0f, 0.1f, // X scale from 1.0 to 0.1
1.0f, 0.1f, // Y scale from 1.0 to 0.1
Animation.RELATIVE_TO_SELF, 0.5f, // Pivot X
Animation.RELATIVE_TO_SELF, 0.5f // Pivot Y
);
zoomOut.setDuration(2000);
zoomOut.setFillAfter(true);
return zoomOut;
}
// Create combined animation
private AnimationSet createCombinedAnimation() {
AnimationSet animationSet = new AnimationSet(true);
AlphaAnimation fadeOut = new AlphaAnimation(1.0f, 0.0f);
fadeOut.setDuration(1500);
ScaleAnimation zoomOut = new ScaleAnimation(
1.0f, 0.0f, 1.0f, 0.0f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f
);
zoomOut.setDuration(1500);
animationSet.addAnimation(fadeOut);
animationSet.addAnimation(zoomOut);
animationSet.setFillAfter(true);
return animationSet;
}
Key Animation Properties​
- Duration: Time for animation to complete
- FillAfter: Keep final state after animation
- FillBefore: Keep initial state before animation
- RepeatCount: Number of repetitions
- RepeatMode: Restart or reverse
- Interpolator: Animation timing curve